/////////////////////////////////////////////////////////////////////////////
//
//  Fifteen Puzzle
//  Kolonitsky Developers Alliance (c) 2012
//  All rights received
//
/////////////////////////////////////////////////////////////////////////////

package view.states
{
    import caurina.transitions.Tweener;

    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    import model.types.DirectionName;
    import model.vo.PuzzleVO;

    import org.kolonitsky.alexey.utils.ArrayUtils;

    import view.events.GameEvent;

    public class InitializeState implements IState
    {

        //-----------------------------
        // game
        //-----------------------------

        private var _game:PuzzleVO = null;

        public function get game():PuzzleVO
        {
            return _game;
        }


        //-------------------------------------------------------------------
        // Methods
        //-------------------------------------------------------------------

        public function InitializeState()
        {
            _skin = new Sprite();

            shuffleTimer = new Timer(Config.MOVE_DELAY, Config.SHUFFLE_STEP);
            shuffleTimer.addEventListener(TimerEvent.TIMER, shufleTimer_timerHandler);
            shuffleTimer.addEventListener(TimerEvent.TIMER_COMPLETE, shuffleTimer_completeHandler);
        }


        //-------------------------------------------------------------------
        //
        //  IState Implementation
        //
        //-------------------------------------------------------------------

        public function displayGame(game:PuzzleVO):void
        {
            _game = game;

            //Change tile position
            var x0:Number = Config.BOARD_LEFT;
            var y0:Number = Config.BOARD_TOP;

            for (var i:int = 0; i < Config.BOARD_CELLS; i++)
            {
                var colIndex:int = i % Config.BOARD_WIDTH;
                var rowIndex:int = int((i - colIndex) / Config.BOARD_WIDTH);
                var number:uint = game.fields[i];
                var tile:Bitmap = _number[number];
                Tweener.addTween(tile, {
                    x: x0 + colIndex * Config.TILE_WIDTH,
                    y: y0 + rowIndex * Config.TILE_HEIGHT,
                    rotation: 0.0,
                    alpha: 1.0,
                    time: Config.TILE_ANIMATION_SPEED
                });
            }
        }


        public function activate():void
        {
            shuffleTimer.start();
        }

        public var _skin:Sprite = null;

        public function get skin():Sprite
        {
            return _skin;
        }

        private var _number:Vector.<Bitmap>;

        public function get numbers():Vector.<Bitmap>
        {
            return _number;
        }

        public function set numbers(value:Vector.<Bitmap>):void
        {
            _number = value;
        }

        //-------------------------------------------------------------------
        //
        //  Private
        //
        //-------------------------------------------------------------------

        private var shuffleTimer:Timer;
        private var lastDirection:String = "";

        private function getAvailableDirections():Array
        {
            var emptyCellIndex:int = game.fields.indexOf(Config.EMPTY_CELL_CODE);
            var result:Array = [];
            var colIndex:int = int(emptyCellIndex % Config.BOARD_WIDTH);
            var rowIndex:int = int((emptyCellIndex - colIndex) / Config.BOARD_WIDTH);

            if (rowIndex > 0 && lastDirection != DirectionName.BOTTOM)
                result.push(DirectionName.TOP);
            if (colIndex < Config.BOARD_WIDTH - 1 && lastDirection != DirectionName.LEFT)
                result.push(DirectionName.RIGHT);
            if (rowIndex < Config.BOARD_HEIGHT - 1 && lastDirection != DirectionName.TOP)
                result.push(DirectionName.BOTTOM);
            if (colIndex > 0 && lastDirection != DirectionName.RIGHT)
                result.push(DirectionName.LEFT);

            return result;
        }

        private function shufleTimer_timerHandler(event:Event):void
        {
            var availableDirections:Array = getAvailableDirections();
            ArrayUtils.shuffle(availableDirections);

            lastDirection = availableDirections[0];
            _skin.dispatchEvent(new GameEvent(GameEvent.MOVE, true, false, lastDirection));
        }

        private function shuffleTimer_completeHandler(event:Event):void
        {
            shuffleTimer.reset();
            _skin.dispatchEvent(new GameEvent(GameEvent.START, true, false));
        }
    }
}
